﻿namespace ThreeByte.ActiveDeck.Dashboard
{
    using System.Windows.Controls;
    using System.Windows.Navigation;
    using System;
    using ActiveDeck.Dashboard.LoginUI;
    using System.Windows.Data;
    using System.ComponentModel;
    using ThreeByte.ActiveDeck.Web.Models;
    using ThreeByte.ActiveDeck.Web;
    using System.ServiceModel.DomainServices.Client;
    using System.Windows.Input;
    using System.ComponentModel.DataAnnotations;

    /// <summary>
    /// Home page for the application.
    /// </summary>
    public partial class ParticipantDetails : Page
    {
        /// <summary>
        /// Creates a new <see cref="Participants"/> instance.
        /// </summary>
        public ParticipantDetails() {
            InitializeComponent();

            NewUserNameTextBox.DataContext = NewUserToAdd;
        }

       

        private NewUser NewUserToAdd = new NewUser();

        /// <summary>
        /// Executes when the user navigates to this page.
        /// </summary>
        protected override void OnNavigatedTo(NavigationEventArgs e) {
            if(this.NavigationContext.QueryString.ContainsKey("pres")) {
                string pres = this.NavigationContext.QueryString["pres"];

                //Change the look based on whether or not it is an approved presentation or not
                _dashboardAccess.IsAuthorizedPresenter(pres, VerifyAccess_Complete, pres);
            } else {
                ErrorWindow.CreateNew("Invalid Presentation ID" + Environment.NewLine + Environment.NewLine + "Presentation Details could not be loaded");
            }
        }

        private DashboardAccessContext _dashboardAccess = new DashboardAccessContext();

        private void VerifyAccess_Complete(InvokeOperation<bool> op) {
            if(!(op.HasError) && op.Value) {
                PresentationDataSource.QueryParameters.Add(new Parameter() { ParameterName = "presentationId", Value = (string)(op.UserState) });
                PresentationDataSource.Load();

                ApprovedDataSource.QueryParameters.Add(new Parameter() { ParameterName = "presentationId", Value = (string)(op.UserState) });
                ApprovedDataSource.Load();

                PresentationParticipantDataSource.QueryParameters.Add(new Parameter() { ParameterName = "presentationId", Value = (string)(op.UserState) });
                PresentationParticipantDataSource.Load();
            } else {
                ErrorWindow.CreateNew("Invalid Presentation ID" + Environment.NewLine + Environment.NewLine + "You are not authorized to access this presentation");
            }
        }

        private void ApproveButton_Click(object sender, System.Windows.RoutedEventArgs e) {
            Button button = (Button)sender;

            ApprovedUser user = (ApprovedUser)(button.Tag);
            user.Approved = true;
            user.Blocked = null;
            user.ApprovedAt = DateTime.Now;
            user.ApprovedBy = WebContext.Current.User.Name;

            ApprovedDataSource.SubmitChanges();
        }

        private void BlockButton_Click(object sender, System.Windows.RoutedEventArgs e) {
            Button button = (Button)sender; 
            ApprovedUser user = (ApprovedUser)(button.Tag);
            user.Approved = false;
            user.ApprovedAt = null;
            user.ApprovedBy = null;
            user.Blocked = true;

            ApprovedDataSource.SubmitChanges();
        }

        private void UnapproveButton_Click(object sender, System.Windows.RoutedEventArgs e) {
            Button button = (Button)sender; 
            ApprovedUser user = (ApprovedUser)(button.Tag);
            user.Approved = false;
            user.ApprovedAt = null;
            user.ApprovedBy = null;
            user.Blocked = null;

            ApprovedDataSource.SubmitChanges();
        }

        

        private void AddNewUserButton_Click(object sender, System.Windows.RoutedEventArgs e) {
            AddNewApprovedUser();
        }

        private void AddNewApprovedUser() {
            //Validate the textbox
            BindingExpression userNameBinding = NewUserNameTextBox.GetBindingExpression(TextBox.TextProperty);
            userNameBinding.UpdateSource();

            Validation.GetHasError(NewUserNameTextBox);

            if(Validation.GetHasError(NewUserNameTextBox)) {
                return;
            }
            string username = NewUserToAdd.Email;
            NewUserToAdd.Reset();

            try {
                ApprovedUser newUser = new ApprovedUser();
                newUser.UserName = username;
                newUser.PresentationID = PresentationIdentifier.Text;
                newUser.Approved = true;
                newUser.ApprovedAt = DateTime.Now;
                newUser.ApprovedBy = WebContext.Current.User.Name;

                ApprovedDataSource.DataView.Add(newUser);
                ApprovedDataSource.SubmitChanges();
            } catch(Exception ex) {
                //Handle duplicate entry exceptions
                Console.WriteLine("Error submiting new user: {0}", ex);
            }
        }

        private void NewUser_KeyDown(object sender, KeyEventArgs e) {
            if(e.Key == Key.Enter) {
                AddNewApprovedUser();
            }
        }

        private void PresentationDataSource_LoadedData(object sender, LoadedDataEventArgs e) {
            Presentation thePresentation = null;
            //TODO: Will only return one - is there a better way to do this?
            foreach(Presentation p in e.Entities) {
                thePresentation = p;
            }

            if(thePresentation.UserAccess == 2) {  //Approved
                ApprovalsTab.Visibility = System.Windows.Visibility.Visible;
                ApprovalsTab.IsSelected = true;
            } else {
                ApprovalsTab.Visibility = System.Windows.Visibility.Collapsed;
                ApprovalsTab.IsSelected = false;
            }
        }

        private void PresentationParticipantDataSource_LoadedData(object sender, LoadedDataEventArgs e) {

        }
    }

    public class NewUser : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private string email;
        
        [Required]
        [StringLength(100, MinimumLength=5)]
        [RegularExpression(@"^(?("")("".+?""@)|" +
                           @"(([0-9a-zA-Z]((\.(?!\.))|" +
                           @"[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-zA-Z])@))" +
                           @"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|" +
                           @"(([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,6}))$",
                           ErrorMessage = @"This does not appear to be a valid email address")]
        [System.Diagnostics.DebuggerNonUserCode()]
        public string Email {
            get {
                return email;
            }
            set {
                Validator.ValidateProperty(value, new ValidationContext(this, null, null) { MemberName = "Email" });
                email = value;
                if(PropertyChanged != null){
                    PropertyChanged(this, new PropertyChangedEventArgs("Email"));
                }
            }
        }

        public void Reset() {
            email = null;
            if(PropertyChanged != null) {
                PropertyChanged(this, new PropertyChangedEventArgs("Email"));
            }
        }
    }
}